package implementation.search;


import anaydis.search.SymbolTable;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

public abstract class AbstractOrderedArray<K, V> implements SymbolTable<K , V> {

    protected EntryI<K, V>[] array;
    protected int amount;


    public int size() {
        return amount;
    }

    public boolean isEmpty() {
        return amount == 0;
    }

    public boolean containsKey(K key) {
        if (key.equals(null)) {
            throw new NullPointerException("Null Key");
        }
        int i = search(key);
        return (i != -1);
    }

    public V get(K key) {
        if (key.equals(null)) {
            throw new NullPointerException("Null Key");
        }
        int i = search(key);
        if (i == -1) {
            return null;
        }
        return array[i].getValue();
    }

    public V put(K key, V value) {
        if (amount >= array.length - 1) {
            duplicateArray();
        }
        int i = search(key);
        V v = null;
        if (i >= 0) {
            v = array[i].getValue();
            array[i] = new EntryI(key, value);
        } else {
            int k = amount;
            if (k != 0) {
                while (k > 0 && (key.hashCode() - (array[k - 1].getKey().hashCode()) < 0)) {
                    array[k] = array[k - 1];
                    k--;
                }
            }
            array[k] = new EntryI(key, value);
            amount++;
        }
        return v;
    }

    private void duplicateArray() {
        EntryI[] aux = new EntryI[amount * 2];
        for (int i = 0; i < amount; i++) {
            aux[i] = array[i];
        }
        array = aux;
    }

    public void clear() {
        int n = array.length;
        array = new EntryI[n];
        amount = 0;
    }

    public Set entrySet() {
        Set<EntryI<K, V>> set = new HashSet<EntryI<K, V>>();
        set.addAll(Arrays.asList(array));
        return set;
    }

    public abstract int search(K key);

}
